package net.vinote.smart.platform.timer;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;

import net.vinote.smart.platform.module.log.RunLogger;
import net.vinote.smart.platform.timer.TimerTask.TimerTaskStatus;

import org.apache.commons.lang.IllegalClassException;

public class TimerManager {
	private Map<String, AbstractSmartTimerTask> taskMap = new ConcurrentHashMap<String, AbstractSmartTimerTask>();
	private static TimerManager instance;

	private TimerManager() {
	}

	public static TimerManager getInstance() {
		if (instance == null) {
			synchronized (TimerManager.class) {
				if (instance == null) {
					instance = new TimerManager();
				}
			}
		}
		return instance;
	}

	public synchronized void schedule(String id, long start, long finish,
			long period, String taskClass) throws Exception {
		final long currentTimeMillis = System.currentTimeMillis();
		// 定时任务结束时间
		if (finish > 0 && finish < currentTimeMillis) {
			RunLogger.getLogger().log(Level.FINER,
					"task is Deprecated,ignore it");
			cancleTask(id);
			return;
		}

		if (taskMap.containsKey(id)
				&& !taskMap.get(id).getClass().getName().equals(taskClass)) {
			cancleTask(id);
		}
		AbstractSmartTimerTask timerTask = taskMap.get(id);
		if (timerTask == null) {
			Class<?> clazz = Class.forName(taskClass);
			Object obj = clazz.newInstance();
			if (!(obj instanceof AbstractSmartTimerTask)) {
				throw new IllegalClassException("invalid timer task class");
			}
			timerTask = (AbstractSmartTimerTask) obj;
			long delay = start - currentTimeMillis;
			if (delay > 0) {
				timerTask.setDelay(delay);
			}
			timerTask.terminalTime = finish;
			timerTask.period = period;
			timerTask.schedule();
			taskMap.put(id, timerTask);
		} else {
			synchronized (timerTask.lock) {
				if (start > currentTimeMillis) {
					timerTask.nextExecutionTime = start;
				}
				timerTask.terminalTime = finish;
				timerTask.period = period;
			}
		}
	}

	public TimerTaskStatus getTaskStatus(String id) {
		TimerTask unit = taskMap.get(id);
		return unit == null ? null : unit.state;
	}

	/**
	 * 取消任务
	 * 
	 * @param id
	 */
	public synchronized void cancleTask(String id) {
		TimerTask unit = taskMap.remove(id);
		if (unit != null) {
			unit.cancel();
		}
	}

}
